package com.ddyx.common.utils.token;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * <p>
 *      ## JWT
 * # header:凭证(校验的变量名), expire:有效期1天(单位:s), secret:秘钥(普通字符串)
 *      app.jwt.header=token
 *      app.jwt.expire=5184000
 *      app.jwt.secret=aHR0cHM6Ly9teS5vc2NoaW5hLm5ldC91LzM2ODE4Njg=
 * </p>
 * created by IntelliJ IDEA.
 * program: ddyx-platform
 * package: com.ddyx.common.util
 * class: JwtTokenUtil.java
 * author: agula
 * since: 2019-07-16  15:59
 */
@Slf4j
@Component
//@ConfigurationProperties(prefix = "app.jwt")
public class JwtTokenUtil {

    /**
     * 加密秘钥
     */
    private String secret="aHR0cHM6Ly9teS5vc2NoaW5hLm5ldC91LzM2ODE4Njg=";
    /**
     * 有效时间
     */
    private long expire=5184000;
    /**
     * 用户凭证
     */
    private String header="token";

    /**
     * 生成Token签名
     * @param userId 用户ID
     * @return 签名字符串
     */
    public String generateToken(long userId) {
        System.out.println("header=" + header + ", expire=" + expire + ", secret=" + secret);
        Date nowDate = new Date();
        // 过期时间
        Date expireDate = new Date(nowDate.getTime() + expire * 1000);
        return Jwts.builder().setHeaderParam("typ", "JWT")
                .setSubject(String.valueOf(userId))
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
        // 注意: JDK版本高于1.8, 缺少 javax.xml.bind.DatatypeConverter jar包,编译出错
    }

    /**
     * 获取签名信息
     * @param token
     */
    public Claims getClaimByToken(String token) {
        try {
            return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            log.debug("validate is token error ", e);
            return null;
        }
    }

    /**
     * 判断Token是否过期
     * @param expiration
     * @return true 过期
     */
    public boolean isTokenExpired(Date expiration) {
        return expiration.before(new Date());
    }
}
